package tiled.simple.gwt.client;

import java.util.HashMap;

import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.World;

import tiled.simple.core.Map;
import tiled.simple.core.ObjectGroup;

import com.google.gwt.canvas.dom.client.Context2d;
import com.google.gwt.canvas.dom.client.CssColor;
import com.google.gwt.event.dom.client.MouseMoveEvent;

public class Game {
	public static final float PIXEL_PER_METER=500;
 	
	private Map map;
	
	public Map animationGraphics;
	public ObjectGroup animations;

	public Camera camera=new Camera();
	public MapRenderer mapRenderer=new MapRenderer(camera);
	
	public World world;
	private JBox2DGWTTestbed testbed;
	private MapShapesProvider mapShapesProvider;
	private MapObjectsProvider mapObjectsProvider;
	
	public GameContactListener contactListener;
	
	public Controls controls;
	
	private FPSCounter fps=new FPSCounter();
	
	public Game(HashMap<String,Map> maps,Controls controls) {
		
		this.controls=controls;
		this.map=maps.get("/level.tmx");
		this.animationGraphics=maps.get("/graphics.tmx");
		this.animations=animationGraphics.getObjectGroup("animations");
		
		boolean doSleep = true;
		Vec2 gravity = new Vec2(0.0f, 10.0f);
		this.world = new World(gravity,doSleep);
		
		//setup contact listener
		this.contactListener = new GameContactListener();
		world.setContactListener(contactListener);
		
		testbed = new JBox2DGWTTestbed(this.world);
		mapShapesProvider = new MapShapesProvider(this.world);
		mapObjectsProvider = new MapObjectsProvider(this);
		
		map.getObjectGroup("collision").loadShapes(mapShapesProvider);
		map.getObjectGroup("entities").loadObjects(mapObjectsProvider);
		
		mapWidth=map.getWidth()*map.getTileWidth();
		mapHeight=map.getHeight()*map.getTileHeight();
		
	}
	
	private int canvasWidth=0;
	private int canvasHeight=0;

	private int mapWidth=0;
	private int mapHeight=0; 
		
	public void render(Context2d context,int refreshRate) {
		world.step((float)refreshRate/1000, 100, 100);
		
		mapRenderer.context=context;

        context.setFillStyle(CssColor.make("rgba(0,0,0, 255)"));
        context.fillRect(0,0,canvasWidth,canvasHeight);
        context.setFillStyle(CssColor.make("rgba(255,255,255, 255)"));
        context.fillText("fps="+fps.get(), 32, 32);
        context.fill();

        camera.update();

		context.translate(((canvasWidth)/2-camera.x), ((canvasHeight/2-camera.y)));

		map.render(mapRenderer);
		mapObjectsProvider.render(context);
//		testbed.render(context);

		context.translate(-((canvasWidth)/2-camera.x), -((canvasHeight)/2-camera.y));
		
		fps.frame();
		

    }
	
	public void resize(int canvasWidth, int canvasHeight) {
		this.canvasWidth=canvasWidth;
		this.canvasHeight=canvasHeight;
	}

	public void onMouseMove(MouseMoveEvent event) {
		Vec2 gravity=new Vec2(-(canvasWidth/2-event.getX()),-(canvasHeight/2-event.getY()));
		
		gravity.normalize();
		world.setGravity(gravity.mul(10f));
	}

}
